package com.cambright.lotusroot 
{	
	import com.cambright;
	import com.cambright.Enumerator;
	
	import flash.desktop.NativeApplication;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filesystem.File;
	import flash.utils.clearInterval;
	import flash.utils.setInterval;
	
	public class Application 
	{	
		static internal var $CURRENT:Application;
		
		use namespace lotusroot_internal;
		static lotusroot_internal var $INTERNAL_NEW:Boolean = false;
		
		internal var $commandMap:CommandMap;
		internal var $moduleVec:Vector.<Module>;
		private var _step:int = -1;
		private var _intervalID:int;
		
		public function Application(application:Sprite) 
		{
			if(!$INTERNAL_NEW) throw Exception.APP_NEW;
			
			$CURRENT = this;
			
			NativeApplication.nativeApplication.autoExit = false;
			application.stage.nativeWindow.visible = false;
			application.stage.addEventListener(Event.FRAME_CONSTRUCTED, _onFrame);
			
			$commandMap = new CommandMap();
			$moduleVec = new Vector.<Module>();
			
			_addEventListeners();

			$step();
		}
		
		private function _addEventListeners():void {}
		
		internal function $notify(command:Command):*
		{
			var key:Class = cambright.getDefinitionByInstance(command);
			
			if(!$commandMap.$apply(key)) throw Exception.COMMAND_NOT_BE_RELATED;
			
			var handler:Handler = CommandMap.$HANDLER;
			handler.$exec(command, CommandMap.$MODULE);
			var result:* = handler.result;
			handler.result = null;
			CommandMap.$CLEAR();
			return result;
		}
		
		internal function $step():void
		{
			++ _step;
			_intervalID = setInterval(_invoke, 1000);
		}
		
		private function _invoke():void
		{
			clearInterval(_intervalID);
			
			switch(_step)
			{
				case 0:$Library.HUB.load();break;
				case 1:$Module.INSTALLER.launch();break;
			}
		}
		
		private function _onFrame(event:Event):void
		{
			var enumerator:Enumerator = new Enumerator($moduleVec);
			while(enumerator.next())
				(enumerator.current as Module).$update();
			enumerator.dispose();
		}
		
		public function installModule(qname:String):void
		{
			$Module.INSTALLER.add(qname);
		}
		
		public function addLibrary(folder:File):void
		{
			if(folder == null) return;
			$Library.HUB.add(folder);
		}
	}
}